import React, { useState, useEffect } from 'react';
import { connect } from 'dva';
import {
  DatePicker,
  Select,
  Input,
  Button,
  Form,
  TreeSelect,
  Modal,
  InputNumber,
  ConfigProvider,
} from 'antd';
import zhCN from 'antd/lib/locale/zh_CN';
// import styles from './index.less';

type Rules = {
  required: boolean;
};

type OptionType = {
  label?: string;
  value: any;
};
type EditItem = {
  key: string;
  type: string;
  label: string;
  rules?: Array<Rules>;
  placeholder?: string;
  mode?: 'multiple' | 'tags' | undefined;
  options?: Array<OptionType>;
  render?: React.ReactElement;
  format?: string;
};
type Props = {
  filters: Array<EditItem>;
  dispatch: Function;
  onClose: Function;
  title?: string;
  formLayout?: object;
  onSave: any;
  updateUrl: string;
  createUrl?: string;
  asyncopt?: object;
  preproccess?: Function; //数据预处理
};
const dateFormat = 'YYYY-MM-DD';
const defaultLayout = {
  labelCol: { span: 4 },
  wrapperCol: { span: 20 },
};

const Index = ({
  filters,
  dispatch,
  onClose,
  title,
  formLayout = defaultLayout,
  onSave,
  createUrl,
  updateUrl,
  onShow,
  preproccess,
}: Props) => {
  const [form] = Form.useForm();
  const [visible, setVisible] = useState(false);
  const [initData, setInitData] = useState({});
  let [opts, setOpts] = useState({});
  useEffect(() => {
    filters.forEach(({ options, key, asyncopt }: any) => {
      // 如果 option 为对象，则数据从 models config 中取
      if (asyncopt && asyncopt.url) {
        dispatch({
          type: `$request/post`,
          payload: {
            url: asyncopt.url,
            data: { page: 0, size: 20, ...asyncopt.params },
          },
        }).then((res: Array<any>) => {
          let list = (res.dataList || res).map(item => {
            return {
              label: item.name,
              value: item.uuid,
            };
          });
          opts[key] = list;
          setOpts(opts);
        });
      }
    });
    onShow(show);
    return () => {
      setInitData({});
    };
  }, []);
  const onOk = async () => {
    const valid = await form.validateFields();
    if (!valid) return;
    let data = form.getFieldsValue();
    preproccess && (data = preproccess(data));
    dispatch({
      type: '$request/post',
      payload: {
        url: initData ? updateUrl : createUrl || updateUrl,
        data: {
          ...initData,
          ...data,
        },
      },
    })
      .then(() => {
        dispatch({
          type: '$msg/showToast',
          payload: {
            type: 'success',
            title: '保存成功',
          },
        });
        onSave && onSave(data);
        setInitData({});
        setTimeout(() => {
          form.resetFields();
          setVisible(false);
        }, 0);
      })
      .catch(e => {
        console.log(e);
      });
  };
  const onCancel = () => {
    onClose && onClose();
    setInitData({});
    setTimeout(() => {
      form.resetFields();
      setVisible(false);
    }, 0);
  };

  const getInputComp = (filter: EditItem) => {
    let {
      key,
      type,
      label,
      mode, // 添加select多选模式，数据目前放在sumit回调给主页面去处理
      placeholder,
      options,
      rules,
      render,
      format,
    } = filter;
    let result = null;
    // select options 为对象时，需要异步请求数据 option为字符串时(define.js里面自己定义的数据 不需要异步请求)
    // eslint-disable-next-line no-underscore-dangle
    options = options || opts[key];
    switch (type) {
      case 'text':
        result = (
          <Input
            allowClear
            placeholder={placeholder}
            style={{ width: 240 }}
            disabled
          />
        );
        break;
      case 'input':
        result = (
          <Input allowClear placeholder={placeholder} style={{ width: 240 }} />
        );
        break;
      case 'inputnumber':
        result = <InputNumber placeholder={title} style={{ width: 240 }} />;
        break;
      case 'date':
        result = (
          <DatePicker
            placeholder={placeholder}
            format={format || dateFormat}
            allowClear
            style={{ minWidth: 240 }}
          />
        );
        break;
      case 'select':
        result = (
          <Select
            showSearch
            optionFilterProp="children"
            placeholder={placeholder}
            allowClear
            mode={mode}
            style={{ width: 240 }}
          >
            {options &&
              options.map((v, i) => (
                <Option key={i} value={v.value}>
                  {v.label}
                </Option>
              ))}
          </Select>
        );
        break;
      default:
        result = render || (
          <Input allowClear placeholder={placeholder} style={{ width: 240 }} />
        );
    }
    return (
      <Form.Item key={key} label={label} name={key} rules={rules}>
        {React.cloneElement(result, filter)}
      </Form.Item>
    );
  };

  const show = (initData: object) => {
    setInitData(initData);
    setVisible(true);
  };

  return (
    <ConfigProvider locale={zhCN}>
      <Modal
        title={title || '提醒'}
        visible={visible}
        onOk={onOk}
        okText="确定"
        cancelText="取消"
        onCancel={() => onCancel()}
        destroyOnClose={true}
      >
        {filters.length > 0 && visible && (
          <Form initialValues={initData} {...formLayout} form={form}>
            {filters.map(v => getInputComp(v))}
          </Form>
        )}
      </Modal>
    </ConfigProvider>
  );
};
export default connect((state: any) => state)(Index);
